using System.Linq;
using Abp.Authorization;
using Abp.Authorization.Roles;
using Abp.Authorization.Users;
using Abp.MultiTenancy;
using FutureApp.Authorization;
using FutureApp.Authorization.Roles;
using FutureApp.EntityFramework;
using FutureApp.Users;
using Microsoft.AspNet.Identity;

namespace FutureApp.Migrations.SeedData
{
    public class HostRoleAndUserCreator
    {
        private readonly FutureAppDbContext _context;

        public HostRoleAndUserCreator(FutureAppDbContext context)
        {
            this._context = context;
        }

        public void Create()
        {
            this.CreateHostRoleAndUsers();
        }

        private void CreateHostRoleAndUsers()
        {
            //Admin role for host

            var adminRoleForHost = this._context.Roles.FirstOrDefault(r => r.TenantId == null && r.Name == FutureAppConsts.StaticRole.Host.Admin);
            if (adminRoleForHost == null)
            {
                adminRoleForHost = this._context.Roles.Add(new Role { Name = FutureAppConsts.StaticRole.Host.Admin, DisplayName = FutureAppConsts.StaticRole.Host.Admin, IsStatic = true });
                this._context.SaveChanges();

                //Grant all tenant permissions
                var permissions = PermissionFinder
                    .GetAllPermissions()
                    .Where(p => p.MultiTenancySides.HasFlag(MultiTenancySides.Host))
                    .ToList();

                foreach (var permission in permissions)
                {
                    this._context.Permissions.Add(
                        new RolePermissionSetting
                        {
                            Name = permission.Name,
                            IsGranted = true,
                            RoleId = adminRoleForHost.Id
                        });
                }

                this._context.SaveChanges();
            }

            //Admin user for tenancy host

            var adminUserForHost = this._context.Users.FirstOrDefault(u => u.TenantId == null && u.UserName == User.AdminUserName);
            if (adminUserForHost == null)
            {
                adminUserForHost = this._context.Users.Add(
                    new User
                    {
                        UserName = User.AdminUserName,
                        Name = "System",
                        Surname = "Administrator",
                        EmailAddress = "admin@mydomain.com",
                        IsEmailConfirmed = true,
                        Password = new PasswordHasher().HashPassword(User.DefaultAdminPassword)
                    }
                );

                this._context.SaveChanges();
                this._context.UserRoles.Add(new UserRole(null, adminUserForHost.Id, adminRoleForHost.Id));
                this._context.SaveChanges();
            }
        }
    }
}